制作只有 4KB 大小的永久挂起程序

在我的网络配置中,部分 Docker 容器的服务需要用 Anycast 的方式实现高可用,例如 DNS。 在之前的文章中 ,我的做法是,创建了一个 Busybox 容器运行 tail -f /dev/null 这条命令,永久挂起,不占用 CPU 也永远不会退出,来维持一份网络命名空间给服务程序和 BIRD 共享。 用人话说就是:我自己发明了一遍 Kubernetes 的 Pod。 我不使用 K8S,因为我的节点都是独立的,不组成集群,因此不使用 K8S 的集群功能,另外它的配置也比较复杂。 但是我转念一想,为了网络命名空间建一个 Busybox 容器好像有些大材小用,我还需要手动配置一个 Entrypoint。如果有一个极小的 Docker 镜像,唯一干的事情是等待,那就更好了。 方案一:直接用 Musl + 静态编译做一个 最容易想到的方法就是写一个死循环的 C 程序,不断的用 sleep 之类命令等待。Linux 系统中,Glibc、Musl 等 C 语言运行库提供了一个 pause 函数,暂停程序运行直到程序收到了外部信号。...

静态编译制作微型 Docker 镜像

Docker 镜像中存储的,可以看作是一个个小型 Linux 系统。它们大都以 Debian、Ubuntu 或是 Alpine 作为基础,再在上面安装额外的软件而成。 以完整的 Linux 作为基础的好处就是镜像中会自带常用的命令( ls , cat 等),在镜像构建过程中常常用到。另外它们也带有完善的包管理机制,简单使用 apt-get 就能装好软件,做出一份能用的镜像。但当镜像做出之后,上面这些工具就用不到了,占用了不必要的磁盘空间。另外,完整的操作系统也会带有 SystemD、OpenRC 等管理后台服务的程序,而 Docker 容器常常只用来运行一个程序,后台管理程序就多余了。 虽然 Docker 镜像采用分层设计,将基础的系统镜像(例如 Debian)和上层修改(例如安装的 nginx)分开存储并进行去重,从而减少了重复的空间占用,但没有完全解决问题。例如假设我先基于 Debian 构建了一个镜像 A,过了一个月又构建了镜像 B。但在这一个月中,Debian 的基础镜像进行了升级,...

未雨绸缪:使用后量子时代的加密算法 的插图

未雨绸缪:使用后量子时代的加密算法

现代互联网上,绝大多数网站都已经支持 HTTPS,其使用的 SSL/TLS 加密协议会将用户的请求数据与网站的响应进行加密,以防止信息被路径上的恶意用户窃取或篡改。而 SSL/TLS 协议中的一个重要组成部分是 RSA、ECDSA 等 非对称加密 算法,这些算法的密钥分为 公钥、私钥 两份,公钥可以公开,而私钥则要妥善保管。 在访问 HTTPS 网站时,会经过以下的流程: 网站会将它的 公钥 (以证书形式)发送给浏览器。 浏览器会校验公钥的有效性,防止中间人篡改公钥,从而拦截或监听通信。 浏览器(或操作系统)内置了一组可信任的证书颁发机构(CA)的公钥,通过密码学方法可以确认这份公钥是其中某个颁发机构生成的。 证书颁发机构则会通过一系列方法(多级证书链,物理隔绝的密钥保存设备)来保护他们自己的私钥安全,防止有人窃取他们的私钥来随意生成被信任的证书信息。 浏览器会与证书颁发机构的服务器联系,查询「证书吊销列表」(Certificate Revocation List)。...

自建 DNS 根服务器

随着近期中美对抗的不断升级,国内的部分社交平台上出现了一种担忧,担心美国切断 DNS 系统的根服务器到中国大陆的网络连接,或者在 DNS 根服务器中删除中国的域名记录,从而破坏中国的互联网。 目前已经有很多分析,说明这种情况不太可能出现,大都从以下两种观点出发: DNS 根服务器使用 Anycast 来广播 IP,中国大陆境内实际上是有根服务器的,不会受到关停影响; 从经济/政治上,美国切断 DNS 根服务器对他们自己的弊大于利。 而今天我会从另一种观点出发: 你可以在短时间内自己搭建一个 DNS 根服务器,并且让你的递归 DNS 使用它。 是的,要自己搭建的 DNS 根服务器和目前作为互联网基础服务的 DNS 根服务器在功能上是等同的。 本文更新日志 2020-10-01:处理根 DNS 记录时,把 DS 记录也保留,以更好支持开启了 DNSSEC 的递归解析服务器。 2020-09-05:初始版本。 DNS 解析原理 我们首先回顾下 DNS 解析的流程: 你打开电脑,输入 https://www.lantian....

制作一个优雅的平安经生成器

由于本文内容与所用语言有关,中文、英文版内容有少许差异。 《平安经》简介 《平安经》由(前)吉林公安厅党委副书记、常务副厅长贺电所作,书中内容只是句式「XXX 平安」的简单重复,但书籍售价很高。因此公众质疑本书的出版和出售有索贿嫌疑。 《平安经》的内容格式如下:(来自 维基百科 ) 「眼平安,耳平安,鼻平安」 「上海港平安、深圳港平安、宁波舟山港平安、广州港平安」 「初生平安、满月平安、百天平安、1岁平安、2岁平安、3岁平安」 「孟加拉湾平安、墨西哥湾平安、几内亚湾平安」 我一看到这个格式,就发现它很适合做标签云。那么就让我们开始吧! 最简单的版本 我用的是 Hexo 静态网站系统,只要在主题的 layout 文件夹下新建一个 ping-an-jing.ejs 模板文件,然后在合适的地方插入如下代码: <% site . tags . forEach ( tag => { %> < a href = "<%- url_for(tag.path) %>" > <%= tag....

Bird 配置 BGP Confederation,及模拟 Confederation(2020-06-07 更新)

更新记录 2020-10-01:添加警告,模拟 Confederation 时不能在内网滤掉内部 ASN 2020-06-07:添加 Bird Confederation 的局限,及模拟 Confederation 方法 2020-05-17:最初版本 ISP 内部 BGP 互联方案比较 互联网中各个 ISP(互联网服务提供商)绝大多数都使用 BGP 协议互相交换自己的路由信息。每个 ISP 都会从所在区域的网络信息中心(NIC,例如 APNIC,RIPE)获得一个 ASN(自治域编号),例如中国电信的 ASN 是 4134。然后 ISP 之间通过物理连接(铜缆,光纤,卫星网络等)连接各自的边界路由器,然后在边界路由器上配置 BGP 协议,告诉对方:「我是 AS4134,我这里可以访问到 202.101.0.0/18 这个 IP 段」。与中国电信相连的 ISP 的路由器会接力把这条消息广播下去:「我是 ASXXXX,我距离 202.101.0.0/18 有一格距离」,以此类推。各个 ISP 的路由器就会根据到目标的距离等参数,把数据包发送到对这个路由器来说最优的目标。 (注:以上内容经过简化,...

x32 ABI 及相应 Docker 容器使用

x32 架构是怎么回事呢?x86、x86_64 架构相信大家都很熟悉,但是 x32 是怎么回事呢,下面就让小编带大家一起了解吧。 x32 架构,其实就是 x86 和 x86_64 架构拼在一起,大家可能会很惊讶 x86 和 x86_64 架构怎么会拼在一起呢?但事实就是这样,小编也感到非常惊讶。 x86 及 x86_64 的历史,以及 x32 ABI 我们现在使用的个人计算机及服务器绝大多数都使用 x86_64 架构,该架构由 AMD 于 2000 年发布规范,2003 年发布第一块处理器。x86_64 是一个 64 位的架构,意味着在 x86_64 中,CPU 的每个寄存器都能保存 64 bit 的数据(即 8 个字节)。在 x86_64 流行之前,多数电脑都使用 Intel 处理器以及相应的 x86 架构/指令集,这是一个 32 位的架构,每个寄存器可以保存 32 bit 的数据(即 4 个字节)。 64 位架构的一个显著好处是内存寻址能力的提升。计算机在访问内存时通常按照这样一个流程:将要访问的内存地址写入寄存器,...

写一个简单的 Telegram 机器人

应 DN42 Telegram 群 群友的要求,我打算给我的 Bird Looking Glass 加上 Telegram Bot 的支持,方便群友现场查询 Whois、测试网络通断、检查 漏油 路由泄漏源头等。这个 Bot 要能识别以斜线 / 开头的命令,然后对命令消息进行回复。 我的 Looking Glass 使用 Go 语言写成,因此我一开始先查找了 Go 语言的 Telegram Bot API。但流行的 API 库无一例外都遵循了同样的请求结构: Telegram 服务器发送一个回调到自己的服务器; 自己的程序处理请求,期间可能根据本地配置的 Token 向 Telegram 服务器多次主动请求; 自己的程序最终主动请求 Telegram 服务器,发送回复信息。 这套方案功能强大,但有点复杂,而多余的功能我根本用不上。我更希望使用 Telegram 官方提供的另一种方式 ,直接回复回调 HTTP 请求的方式: Telegram 服务器发送一个回调到自己的服务器; 自己的程序处理请求后,直接以 HTTP Response 方式回复回调请求,执行操作。...

Docker 容器共享网络命名空间,集成 Bird 实现 Anycast 高可用

正好一年前,我 在 DN42 网络内用 Docker 建立了 Anycast 服务 。当时我的方法是,自定义容器的镜像,在其中安装一个 Bird,然后加入 OSPF 协议的配置文件来广播 Anycast 路由。但是随着时间推移,这套方案出现了以下问题: 安装 Bird 本身是个较花时间的过程。我的 Bird 不是用 apt-get 装的,因为 我的 Dockerfile 需要支持多种 CPU 架构 ,而 Debian 有些架构的软件源里没有 Bird。而又因为我的构建服务器是 AMD64 架构, 使用 qemu-user-static 支持其它架构的镜像运行 ,为其它架构制作镜像、编译程序时就涉及到大量的指令集翻译,效率非常低。构建一个镜像在不同架构下的版本可能需要 2 小时以上,而安装应用本身的 apt-get 流程只需要几分钟。 自己定制镜像也比较花时间。因为容器中需要同时运行目标应用(例如之前的 PowerDNS)和 Bird,就不能直接把目标应用作为 ENTRYPOINT 了,...

使用 PowerDNS 的 Lua 功能自建分地区解析 GeoDNS 的插图

使用 PowerDNS 的 Lua 功能自建分地区解析 GeoDNS

之前,如果要为自己的网站自建权威 DNS 系统,那么(几乎)唯一的选择是 PowerDNS 加上它的 GeoIP 后端。但是 GeoIP 后端使用的是 YAML 格式的配置文件,不能与 MySQL 等数据库一同使用。这意味着必须手动配置一套跨服务器同步文件的系统,而不能使用更为成熟的数据库同步技术。 不过,PowerDNS 在最新的 4.2 版本中加入了 Lua 记录的支持。Lua 是一种专门用于「嵌入其它程序执行功能」的编程语言,你或许曾经在 nginx 上看到过它(作为一个插件)。Lua 记录支持使得 PowerDNS 可以根据用户查询请求的不同来返回不同的回答,分地区解析 GeoDNS 功能也就可以实现了。 更新 PowerDNS 最新的 PowerDNS 4.2 版本没有加入 Debian 10 的软件仓库中,你需要从 Debian Unstable 的软件仓库下载。但是由于 PowerDNS 依赖了一大堆新版的库文件,其中包括系统运行必须的库文件,...